package com.x52im.rainbowchat.http.logic.logic;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.Processor;
import com.eva.framework.dbpool.DBDepend;
import com.eva.framework.dbpool.DBShell;
import com.eva.framework.utils.EndsExceptionFactory;
import com.x52im.rainbowchat.BaseConf;
import com.x52im.rainbowchat.http.dao.UserDAO;
import com.x52im.rainbowchat.http.logic.AbstractJobDispatcher;
import com.x52im.rainbowchat.http.logic.LogicProcessor2;
import com.x52im.rainbowchat.http.logic.LogicUtils;
import com.x52im.rainbowchat.http.logic.dto.RosterElementEntity;
import com.x52im.rainbowchat.http.util.JedisTools;
import com.x52im.rainbowchat.im.dto.CMDBody4AddFriendRequest;
import com.x52im.rainbowchat.im.dto.CMDBody4ProcessFriendRequest;
import com.x52im.rainbowchat.im.impl.ChatLogicManager;
import com.x52im.rainbowchat.im.util.MessageHelper;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

public class SNSJobDispatcher extends AbstractJobDispatcher {
    DBShell db = LogicProcessor2.db;

    /**
     * 维护好友关系管理.
     *
     * @param action_id 维护类型，SysConstant中的操作类型常量
     * @param newData   客端发送过来的本次修改新数据(可能为空，理论上与oldData不会同时空）
     * @param oldData   客端发送过来的本次修改前的老数据(可能为空，理论上与newData不会同时空）
     * @param userName  操作者的用户名
     * @return 返回给客户端的对象
     */
    @Override
    public String dispatch(int action_id, Object newData, Object _oldData, Processor.User user) throws Exception {
        switch (action_id) {
            // 【接口1008-3-7】完成邀请朋友注册的邮件发送
            case ACTION_APPEND1:// ok
            {
                return ACTION_APPEND1(newData);
            }
            // 【接口1008-3-8】查询好友/陌生人的基本信息
            case ACTION_APPEND2:// ok
            {

                return ACTION_APPEND2(newData);
            }
            // 【接口1008-3-9】"忘记密码"
            case ACTION_APPEND3:// ok
            {
                return ACTION_APPEND3(_oldData, newData);
            }
            // 【接口1008-3-23】查找好友之“随机查找”
            case ACTION_APPEND5:// ok
            {
                return ACTION_APPEND5(newData);
            }

            // 【接口1008-3-24】用户A发起的添加好友请求  @since 4.5（）
            // 适用范围：Web端、Android端（待用）、iOS端（待用）
            case ACTION_APPEND6: {
                return ACTION_APPEND6(newData);
            }
            // 【接口1008-3-25】被添加者【同意】加好友请求的处理接口（此处理是由被加者发起的）   @since 4.5
            // 适用范围：Web端、Android端（待用）、iOS端（待用）
            case ACTION_APPEND7: {
                return ACTION_APPEND7(newData);
            }
            // 【接口1008-3-26】被添加者【拒绝】加好友请求的处理接口（此处理是由被加者发起的）   @since 4.5
            // 适用范围：Web端、Android端（待用）、iOS端（待用）
            case ACTION_APPEND8: {
                return ACTION_APPEND8(newData);
            }

            // 忘记密码
            case ACTION_APPEND9: {
                return ACTION_APPEND9(newData);
            }

            // 查询好友/陌生人的基本信息 ACTION_APPEND2 接口的复制品,修改为用电话号码查询
            case ACTION_APPEND10: {
                return ACTION_APPEND10(newData);
            }

            // 设置支付密码
            case ACTION_APPEND11: {
                return ACTION_APPEND11(newData);
            }

            default:
                throw EndsExceptionFactory.INVALID_ACTION_ID(action_id);
        }
    }

    private String ACTION_APPEND11(Object newData) throws Exception {
        JSONObject nwObj = JSONObject.parseObject((String) newData);
        String phone = nwObj.getString("phone");
        String randomCode = nwObj.getString("randomCode");
        String newPsw = nwObj.getString("newPsw");
        String oldPsw = nwObj.getString("oldPsw");

        String status = "1";
        String message = null;
        if (newPsw.length() != 6) {
            message = "支付密码必须是6位数的数字";
            Map map = new HashMap();
            map.put("status", status);
            map.put("message", message);
            return JSON.toJSONString(map);
        }

        if (CommonUtils.isStringEmpty(oldPsw)) {
            // 通过短信验证码修改支付密码
            if (!CommonUtils.isStringEmpty(randomCode)) {
                String key = JedisTools.getSmsPaypswKey(phone);
                String smsValue = JedisTools.get(key);

                if (CommonUtils.isStringEmpty(smsValue)) {
                    message = "请重新获取短信验证码";
                } else {
                    if (!smsValue.equals(randomCode)) {
                        message = "验证码输入错误";
                    } else {
                        UserDAO userDAO = new UserDAO();
                        boolean b = userDAO.updatePayPsw(phone, newPsw);
                        if (b) {
                            JedisTools.delkeyObject(key);
                            status = "0";
                            message = "支付密码设置成功";
                        } else {
                            message = "支付密码设置失败请联系管理员";
                        }
                    }
                }
            }
        } else {
            // 通过旧密码来修改新密码
            String oldPwsEnc = CommonUtils.encyptPassword(oldPsw, "");
            String oldPaypwsDB = db.querySingleItem("pay_psw", "missu_users", "phone='" + phone + "'");
            if (!oldPwsEnc.equals(oldPaypwsDB)) {
                message = "旧支付密码输入错误";
            } else {
                UserDAO userDAO = new UserDAO();
                boolean b = userDAO.updatePayPsw(phone, newPsw);
                if (b) {
                    status = "0";
                    message = "支付密码设置成功";
                } else {
                    message = "支付密码设置失败请联系管理员";
                }
            }
        }

        Map map = new HashMap();
        map.put("status", status);
        map.put("message", message);
        return JSON.toJSONString(map);
    }

    private String ACTION_APPEND10(Object newData) throws Exception {
        JSONObject nwObj = JSONObject.parseObject((String) newData);
        String phone = nwObj.getString("phone");
        String uid = nwObj.getString("uid");
        return JSON.toJSONString(LogicUtils.queryUserInfoByPhoneOrUid(phone, uid));
    }

    private String ACTION_APPEND9(Object newData) throws Exception {
        JSONObject nwObj = JSONObject.parseObject((String) newData);
        String phone = nwObj.getString("phone");
        String randomCode = nwObj.getString("randomCode");
        String newPsw = nwObj.getString("newPsw");

        String status = "1";
        String message = null;

        String key = JedisTools.getSmsFindpswUserKey(phone);
        String smsValue = JedisTools.get(key);
        if (CommonUtils.isStringEmpty(smsValue)) {
            message = "请重新获取短信验证码";
        } else {
            if (!smsValue.equals(randomCode)) {
                message = "验证码输入错误";
            } else {
                UserDAO userDAO = new UserDAO();
                boolean b = userDAO.updateUserPsw(phone, newPsw);
                if (b) {
                    JedisTools.delkeyObject(key);
                    status = "0";
                    message = "密码修改成功";
                } else {
                    message = "密码修改失败请联系管理员";
                }
            }
        }

        Map map = new HashMap();
        map.put("status", status);
        map.put("message", message);
        return JSON.toJSONString(map);
    }

    private String ACTION_APPEND8(Object newData) throws Exception {
        // 解析被添加者拒绝加好友请求原数据（客户端A发过来的）
        CMDBody4ProcessFriendRequest processFriendMetaFromClient =
                MessageHelper.pareseProcessAdd$Friend$Req_B$To$Server_REJECTMessage((String) newData);
        // 进入处理逻辑并返回结果
        ChatLogicManager.processMT09_OF_PROCESS_ADD$FRIEND$REQ_B$TO$SERVER_REJECT(processFriendMetaFromClient);
        return null;
    }

    private String ACTION_APPEND7(Object newData) throws Exception {
        // 解析被添加者同意加好友请求原数据（客户端A发过来的）
        CMDBody4ProcessFriendRequest processFriendMetaFromClient =
                MessageHelper.pareseProcessAdd$Friend$Req_B$To$Server_AGREEMessage((String) newData);
        // 进入处理逻辑并返回结果
        ChatLogicManager.processMT08_OF_PROCESS_ADD$FRIEND$REQ_B$TO$SERVER_AGREE(processFriendMetaFromClient);
        return null;
    }

    private String ACTION_APPEND6(Object newData) throws Exception {
        // 解析添加好友请求原数据（客户端A发过来的）
        CMDBody4AddFriendRequest addFriendMetaFromClient =
                MessageHelper.pareseAddFriendRequestMessage((String) newData);
        // 进入处理逻辑并返回结果
        ChatLogicManager.processMT05_OF_ADD_FRIEND_REQUEST_A$TO$SERVER(addFriendMetaFromClient);
        return null;
    }

    private String ACTION_APPEND5(Object newData) throws Exception {
        JSONObject nwObj = JSONObject.parseObject((String) newData);

        // 本地用户的uid：用于查询结果中排除“自已”
        String user_uid = nwObj.getString("local_uid");
        // 性别查询条件：-1 表示不使用本条件，1  表只查男性，0  表只查女性
        String user_sex = nwObj.getString("sex_condition");
        // 在线状态查询条件：-1 表示不使用本条件，1  表只查在线，0 表只查离线
        String is_online = nwObj.getString("online_condition");

        String sql = "";
        if (DBShell.isSQLServer()) {
            // SQL Server数据库随机取前10条记录的方法是：top 10和order by newid()即可实现
            sql = MessageFormat.format(LogicUtils.getUSER_INFI_RANDOM_SQL(user_uid)
                    , "top 10"
                    , user_uid
                    , user_sex.equals("-1") ? "" : " and user_sex=" + user_sex
                    , is_online.equals("-1") ? "" : " and is_online=" + is_online
                    , "newid()");
        } else if (DBShell.isMySQL()) {
            // MySQL数据库随机取前10条记录的方法是：order by rand() limit 0,10 即可实现
            sql = MessageFormat.format(LogicUtils.getUSER_INFI_RANDOM_SQL(user_uid)
                    , ""
                    , user_uid
                    , user_sex.equals("-1") ? "" : " and user_sex=" + user_sex
                    , is_online.equals("-1") ? "" : " and is_online=" + is_online
                    , "rand() limit 0,10");
        }

        Vector<Vector> vec = db.queryData(sql);
        ArrayList<RosterElementEntity> friendInfoList = new ArrayList<RosterElementEntity>();
        if (vec.size() > 0) {
            for (Vector<String> row : vec) {
                friendInfoList.add(LogicUtils.constructUserInfo(row.toArray()));
            }
        }

        return JSON.toJSONString(friendInfoList);
    }

    private String ACTION_APPEND3(Object _oldData, Object newData) throws Exception {
        Object[] objs = (Object[]) _oldData;

        Vector sqls = new Vector();
        Vector values = new Vector();

        // 要发送“重置密码”邮件的接收邮箱
        final String emailAddr = (String) newData;

        // 尝试查询此邮箱对应的注册信息
        RosterElementEntity userInfo = LogicUtils.queryUserInfo(emailAddr, null);

        // 邀请邮件正文
        String responseMainContent = null;
        String responseSubject = null;
        // 表示没有此邮箱的注册信息
        if (userInfo == null) {
            // 如果该邮箱未注册，则发送的邮件内容是错误信息，信息内会引导用户用此邮箱来注册（详见邮件模板哦）
            responseMainContent = BaseConf.getInstance()
                    .getSNS_RESPONSE_FOR_FORGOTPSW_ERROR_TEMPLATE(emailAddr);
            responseSubject = BaseConf.getInstance().getSNS_RESPONSE_FORGOT_PSW_ERROR_MAIL_SUBJECT();
        }
        // 该注册邮件存在情交下，发送的邮件内容就是注册信息以及重置密码链接（详见邮件模板哦）
        else {

            String verificationCode = CommonUtils.getRandomStr2(8);
            sqls.add("UPDATE missu_users SET verification_code=?, verification_time="
                    + DBDepend.getDefaultDatetimeFunc() + " WHERE user_mail=?");
            values.add(new Object[]{verificationCode, emailAddr});
            db.update(sqls, values, false);

            String path = objs[0] + "view/redirectToForget.jsp?loginName=" + userInfo.getUser_uid() + "&verificationCode=" + verificationCode;
            responseMainContent = BaseConf.getInstance().getSNS_RESPONSE_FOR_FORGOTPSW_TEMPLATE(
                    userInfo.getNickname(), userInfo.getUser_uid(), userInfo.getUser_mail(), verificationCode, path);
            responseSubject = BaseConf.getInstance().getSNS_RESPONSE_FORGOT_PSW_MAIL_SUBJECT();
        }

        // * 注充说明：如果用户输入的是一个不存在的邮箱，只要邮箱格式合法，服务
        // * 端是没有办法也没有必要知道这个邮箱是否是真的存在，反正只管发就是了。

        // 邮件发送是个缓慢的过程，为了不影响接口调用者的体验，所以用异步线程发送
        LogicUtils.sendMailAsync(emailAddr, responseSubject, responseMainContent, "忘记密码");

        return null;
    }

    private String ACTION_APPEND2(Object newData) throws Exception {
        JSONObject nwObj = JSONObject.parseObject((String) newData);

        // true表示用用户或女孩友的mail地址，否则表示用用户或好友的uid
        boolean useMail = "1".equals(nwObj.getString("use_mail"));
        // 用户或的mail地址
        String mailOfFriend = nwObj.getString("friend_mail");
        // 用户或好友的uid
        String uidOfFriend = nwObj.getString("friend_uid");

        // 查询发起人的uid，这个uid指的是客户端提起这个查询时的当前登陆者uid，
        // 指明此uid后本sql将同时提供被查询作为好友的额外信息。本参数可为null（表示不需要查询好友的额外信息）
        String myUid = nwObj.getString("my_uid");

        return JSON.toJSONString(LogicUtils.queryUserInfo(useMail, mailOfFriend, uidOfFriend, myUid));
    }

    private String ACTION_APPEND1(Object newData) {
        JSONObject nwObj = JSONObject.parseObject((String) newData);

        // 接收邀请的email地址
        String sendToMailAddr = nwObj.getString("receiver_mail");
        // 发起邀请人的昵称
        String fromNickName = nwObj.getString("local_nickname");
        // 发起邀请人的email（作为被邀请人加好友的凭证）
        String fromMail = nwObj.getString("local_mail");
        // 发起邀请人的uid（作为被邀请人加好友的凭证）
        String fromUid = nwObj.getString("local_uid");

        // 邀请邮件正文
        String inviteMainContent = BaseConf.getInstance()
                .getSNS_INVITE_MAIL_CONTENT(fromNickName, fromMail, fromUid);

        // * 注充说明：如果用户输入的是一个不存在的邮箱，只要邮箱格式合法，服务
        // * 端是没有办法也没有必要知道这个邮箱是否是真的存在，反正只管发就是了。

        // 邮件发送是个缓慢的过程，为了不影响接口调用者的体验，所以用异步线程发送
        LogicUtils.sendMailAsync(
                sendToMailAddr
                , MessageFormat.format(BaseConf.getInstance().getSNS_INVITE_MAIL_SUBJECT(), fromNickName)
                , inviteMainContent
                , "邀请朋友");

        return null;
    }
}
